package com.doubao.chat.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.doubao.chat.dto.ChatContextDTO;
import com.doubao.chat.dto.ChatMessageDTO;
import com.doubao.chat.dto.ChatSessionDTO;
import com.doubao.chat.dto.MessageProviderInfo;
import com.doubao.chat.dto.VoiceConfigDTO;
import com.doubao.chat.dto.request.*;
import com.doubao.chat.entity.ChatMessage;
import com.doubao.chat.entity.ChatSession;
import com.doubao.chat.mapper.ChatMessageMapper;
import com.doubao.chat.mapper.ChatSessionMapper;
import com.doubao.chat.service.AIProviderService;
import com.doubao.chat.service.ChatMessageService;
import com.doubao.chat.service.ChatSessionService;
import com.doubao.common.result.Result;
import com.doubao.device.entity.SmartDevice;
import com.doubao.device.service.DeviceVoiceService;
import com.doubao.device.service.SmartDeviceService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Lazy;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;

/**
 * 聊天会话服务实现类
 */
@Service
@Slf4j
public class ChatSessionServiceImpl extends ServiceImpl<ChatSessionMapper, ChatSession> implements ChatSessionService {

    private final ChatMessageMapper messageMapper;
    private final SmartDeviceService deviceService;
    private final AIProviderService aiProviderService;
    private final DeviceVoiceService voiceService;
    // private final FileService fileService; // 暂时注释掉文件服务相关功能
    private final ChatMessageService chatMessageService;
    private final StringRedisTemplate stringRedisTemplate;

    public ChatSessionServiceImpl(
            ChatMessageMapper messageMapper,
            SmartDeviceService deviceService,
            @Qualifier("AIProviderServiceImpl") AIProviderService aiProviderService, // 使用@Qualifier指定Bean名称
            DeviceVoiceService voiceService,
            @Lazy ChatMessageService chatMessageService,
            StringRedisTemplate stringRedisTemplate) {
        this.messageMapper = messageMapper;
        this.deviceService = deviceService;
        this.aiProviderService = aiProviderService;
        this.voiceService = voiceService;
        this.chatMessageService = chatMessageService;
        this.stringRedisTemplate = stringRedisTemplate;
    }


    @Override
    @Transactional
    public Result<ChatSessionDTO> createSession(Long userId, CreateSessionRequest request) {
        if (userId == null) {
            return Result.failed("用户未登录");
        }

        // 检查智能体是否存在
        SmartDevice device = deviceService.getById(request.getDeviceId());
        if (device == null) {
            return Result.failed("智能体不存在");
        }

        if (device.getStatus() == null || device.getStatus() != 1) {
            return Result.failed("智能体已禁用");
        }

        // 创建会话实体
        ChatSession session = new ChatSession();
        session.setUserId(userId);
        session.setDeviceId(request.getDeviceId());

        // 设置会话标题，如果未提供则使用智能体名称
        String title = StringUtils.hasText(request.getTitle())
                ? request.getTitle()
                : "与" + device.getName() + "的对话";
        session.setTitle(title);

        session.setMessageCount(0);
        session.setLastMessageTime(LocalDateTime.now());
        session.setStatus(1);
        session.setCreatedAt(LocalDateTime.now());
        session.setUpdatedAt(LocalDateTime.now());

        // 保存会话
        save(session);

        // 如果有初始消息，则发送初始消息
        if (StringUtils.hasText(request.getInitialMessage())) {
            SendMessageRequest messageRequest = new SendMessageRequest();
            messageRequest.setSessionId(session.getId());
            messageRequest.setDeviceId(request.getDeviceId());
            messageRequest.setContent(request.getInitialMessage());
            chatMessageService.sendMessage(userId, messageRequest);
        }

        ChatSessionDTO sessionDTO = new ChatSessionDTO();
        BeanUtils.copyProperties(session, sessionDTO);
        sessionDTO.setDeviceName(device.getName());
        sessionDTO.setDeviceAvatar(device.getAvatar());

        return Result.success(sessionDTO);
    }

    @Override
    public Result<IPage<ChatSessionDTO>> getSessionList(Long userId, GetSessionListRequest request) {
        if (userId == null) {
            return Result.failed("用户未登录");
        }

        Page<ChatSession> page = new Page<>(request.getPage(), request.getSize());
        IPage<ChatSession> sessionPage = baseMapper.selectUserSessionList(page, userId, request.getDeviceId());

        // 转换为DTO
        IPage<ChatSessionDTO> dtoPage = sessionPage.convert(session -> {
            ChatSessionDTO dto = new ChatSessionDTO();
            BeanUtils.copyProperties(session, dto);
            return dto;
        });

        return Result.success(dtoPage);
    }

    @Override
    public Result<ChatSessionDTO> getSessionDetail(Long userId, Long sessionId) {
        if (userId == null) {
            return Result.failed("用户未登录");
        }

        // 查询会话
        ChatSession session = getById(sessionId);
        if (session == null || !session.getUserId().equals(userId)) {
            return Result.failed("会话不存在或无访问权限");
        }

        // 查询智能体信息
        SmartDevice device = deviceService.getById(session.getDeviceId());
        if (device == null) {
            return Result.failed("智能体不存在");
        }

        // 构造DTO
        ChatSessionDTO dto = new ChatSessionDTO();
        BeanUtils.copyProperties(session, dto);
        dto.setDeviceName(device.getName());
        dto.setDeviceAvatar(device.getAvatar());

        // 获取最后一条消息
        LambdaQueryWrapper<ChatMessage> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ChatMessage::getSessionId, sessionId)
                .orderByDesc(ChatMessage::getId)
                .last("LIMIT 1");
        ChatMessage lastMessage = messageMapper.selectOne(queryWrapper);
        if (lastMessage != null) {
            dto.setLastMessageContent(lastMessage.getContent());
        }

        return Result.success(dto);
    }

    @Override
    @Transactional
    public Result<Void> updateSession(Long userId, UpdateSessionRequest request) {
        if (userId == null) {
            return Result.failed("用户未登录");
        }

        // 查询会话
        ChatSession session = getById(request.getSessionId());
        if (session == null || !session.getUserId().equals(userId)) {
            return Result.failed("会话不存在或无访问权限");
        }

        // 更新会话标题
        if (StringUtils.hasText(request.getTitle())) {
            session.setTitle(request.getTitle());
            session.setUpdatedAt(LocalDateTime.now());
            updateById(session);
        }

        return Result.success();
    }

    @Override
    @Transactional
    public Result<Void> deleteSession(Long userId, Long sessionId) {
        if (userId == null) {
            return Result.failed("用户未登录");
        }

        // 查询会话
        ChatSession session = getById(sessionId);
        if (session == null || !session.getUserId().equals(userId)) {
            return Result.failed("会话不存在或无访问权限");
        }

        // 保存会话聊天记录为文件
        /*try {
            saveSessionToFile(userId, sessionId);
        } catch (Exception e) {
            log.error("保存会话聊天记录失败", e);
            // 继续进行删除操作，不中断流程
        }*/

        // 逻辑删除会话
        session.setStatus(0);
        session.setUpdatedAt(LocalDateTime.now());
        updateById(session);

        // 删除会话消息
        messageMapper.deleteSessionMessages(sessionId);

        return Result.success();
    }

    @Override
    @Transactional
    public Result<Void> batchDeleteSessions(Long userId, BatchDeleteSessionRequest request) {
        if (userId == null) {
            return Result.failed("用户未登录");
        }

        List<Long> sessionIds = request.getSessionIds();
        if (sessionIds == null || sessionIds.isEmpty()) {
            return Result.failed("会话ID列表不能为空");
        }

        // 保存会话聊天记录为文件
        /*for (Long sessionId : sessionIds) {
            try {
                saveSessionToFile(userId, sessionId);
            } catch (Exception e) {
                log.error("保存会话聊天记录失败, sessionId={}", sessionId, e);
                // 继续进行删除操作，不中断流程
            }
        }*/

        // 批量逻辑删除会话
        baseMapper.batchDeleteSessions(userId, sessionIds);

        // 批量删除会话消息
        messageMapper.batchDeleteMessagesBySessionIds(sessionIds);

        return Result.success();
    }

    @Override
    @Transactional
    public Result<Void> clearSession(Long userId, ClearSessionRequest request) {
        if (userId == null) {
            return Result.failed("用户未登录");
        }

        // 查询会话
        ChatSession session = getById(request.getSessionId());
        if (session == null || !session.getUserId().equals(userId)) {
            return Result.failed("会话不存在或无访问权限");
        }

        // 保存会话聊天记录为文件
        /*try {
            saveSessionToFile(userId, request.getSessionId());
        } catch (Exception e) {
            log.error("保存会话聊天记录失败", e);
            // 继续进行清空操作，不中断流程
        }*/

        // 删除会话消息
        messageMapper.deleteSessionMessages(request.getSessionId());

        // 更新会话信息
        session.setMessageCount(0);
        session.setUpdatedAt(LocalDateTime.now());
        updateById(session);

        return Result.success();
    }

    @Override
    public Result<String> exportSession(Long userId, ExportSessionRequest request) {
        // 暂时注释掉导出会话功能
        return Result.failed("导出会话功能暂未开放");
    }

    @Override
    public Result<ChatContextDTO> getSessionContext(Long userId, Long sessionId) {
        if (userId == null) {
            return Result.failed("用户未登录");
        }

        // 查询会话
        ChatSession session = getById(sessionId);
        if (session == null || !session.getUserId().equals(userId)) {
            return Result.failed("会话不存在或无访问权限");
        }

        // 查询智能体信息
        SmartDevice device = deviceService.getById(session.getDeviceId());
        if (device == null) {
            return Result.failed("智能体不存在");
        }

        // 获取AI提供商信息
        Result<MessageProviderInfo> providerResult = aiProviderService.getProviderInfo(session.getDeviceId());
        if (!providerResult.isSuccess()) {
            return Result.failed(providerResult.getMessage());
        }

        // 获取系统提示词
        Result<String> promptResult = aiProviderService.getSystemPrompt(session.getDeviceId());
        String systemPrompt = promptResult.isSuccess() ? promptResult.getData() : "";

        // 查询会话消息，限制上下文消息数量
        Integer maxContextLength = device.getMaxContextLength() != null ? device.getMaxContextLength() : 10;
        List<ChatMessage> messages = messageMapper.selectContextMessages(sessionId, maxContextLength);
        // 如果消息数量超过限制，只保留最新的消息
        if (messages != null && messages.size() > maxContextLength) {
            messages = messages.subList(messages.size() - maxContextLength, messages.size());
        }
        // 确保消息列表不为null
        if (messages == null) {
            messages = new ArrayList<>();
        }
        // 按时间升序排列，确保消息按照创建时间正确排序
        messages.sort((m1, m2) -> {
            if (m1 == null || m2 == null) return 0;
            if (m1.getCreatedAt() == null && m2.getCreatedAt() == null) return 0;
            if (m1.getCreatedAt() == null) return -1;
            if (m2.getCreatedAt() == null) return 1;
            return m1.getCreatedAt().compareTo(m2.getCreatedAt());
        });

        // 添加系统提示词消息
        if (StringUtils.hasText(systemPrompt)) {
            ChatMessage systemMessage = new ChatMessage();
            systemMessage.setSessionId(sessionId);
            systemMessage.setDeviceId(session.getDeviceId());
            systemMessage.setRole("system");
            systemMessage.setContent(systemPrompt);
            // 设置系统消息的创建时间为最早，确保它始终在消息列表的最前面
            systemMessage.setCreatedAt(messages.isEmpty() ?
                    LocalDateTime.now().minusSeconds(1) :
                    messages.get(0).getCreatedAt().minusSeconds(1));
            messages.add(0, systemMessage);
        }

        // 获取语音配置
        Result<VoiceConfigDTO> voiceResult = getDeviceVoiceConfig(session.getDeviceId());

        // 构造上下文DTO
        ChatContextDTO contextDTO = new ChatContextDTO();

        // 设置会话信息
        ChatSessionDTO sessionDTO = new ChatSessionDTO();
        BeanUtils.copyProperties(session, sessionDTO);
        sessionDTO.setDeviceName(device.getName());
        sessionDTO.setDeviceAvatar(device.getAvatar());
        contextDTO.setSession(sessionDTO);

        // 设置消息列表
        List<ChatMessageDTO> messageDTOs = messages.stream().map(message -> {
            ChatMessageDTO dto = new ChatMessageDTO();
            BeanUtils.copyProperties(message, dto);
            dto.setIsCurrentUser("user".equals(message.getRole()));
            return dto;
        }).collect(Collectors.toList());
        contextDTO.setMessages(messageDTOs);

        // 设置系统提示词
        contextDTO.setSystemPrompt(promptResult.isSuccess() ? promptResult.getData() : "");

        // 设置提供商信息
        contextDTO.setProviderInfo(providerResult.getData());

        // 设置语音配置
        contextDTO.setVoiceConfig(voiceResult.isSuccess() ? voiceResult.getData() : new VoiceConfigDTO());

        return Result.success(contextDTO);
    }

    /**
     * 检查并保存聊天历史记录
     * 首次访问或距离上次保存超过14天时保存
     */
    /*private void checkAndSaveChatHistory(Long userId, Long sessionId, ChatSession session) throws Exception {
        // 注释掉整个方法实现
    }*/

    /**
     * 保存会话聊天记录为文件并返回URL
     */
    /*private String saveSessionToFileAndGetUrl(Long userId, Long sessionId) throws Exception {
        // 注释掉整个方法实现
        return null;
    }*/

    /**
     * 获取设备语音配置
     */
    private Result<VoiceConfigDTO> getDeviceVoiceConfig(Long deviceId) {
        try {
            Result<com.doubao.device.dto.VoiceConfigDTO> voiceResult = voiceService.getDeviceVoiceConfig(deviceId);
            if (voiceResult.isSuccess()) {
                // 转换DTO类型
                VoiceConfigDTO voiceConfig = new VoiceConfigDTO();
                com.doubao.device.dto.VoiceConfigDTO sourceConfig = voiceResult.getData();

                BeanUtils.copyProperties(sourceConfig, voiceConfig);
                // 默认启用语音
                voiceConfig.setEnableVoice(true);
                return Result.success(voiceConfig);
            }
            return Result.failed("获取语音配置失败");
        } catch (Exception e) {
            log.error("获取设备语音配置异常", e);
            return Result.failed("获取语音配置异常");
        }
    }


    @Override
    public ChatSession findRecentSession(Long userId, Long deviceId) {
        if (userId == null || deviceId == null) {
            return null;
        }

        // 查找最近24小时内的会话
        LambdaQueryWrapper<ChatSession> queryWrapper = new LambdaQueryWrapper<ChatSession>()
                .eq(ChatSession::getUserId, userId)
                .eq(ChatSession::getDeviceId, deviceId)
                .eq(ChatSession::getStatus, 1)  // 正常状态
                .ge(ChatSession::getLastMessageTime, LocalDateTime.now().minusHours(24))
                .orderByDesc(ChatSession::getLastMessageTime)
                .last("LIMIT 1");

        return getOne(queryWrapper);
    }

    /**
     * 保存会话聊天记录为文件
     */
    /*private void saveSessionToFile(Long userId, Long sessionId) throws Exception {
        // 注释掉整个方法实现
    }*/

    /**
     * 导出会话聊天记录为指定格式文件
     */
    /*private String exportSessionToFile(Long userId, Long sessionId, String format) throws Exception {
        // 注释掉整个方法实现
        return null;
    }*/
}